package com.alon.spring01.study.async;

import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.util.concurrent.*;

/**
 * @program: spring01
 * @description: CompletableFuture测试类
 * @author: yulongguang
 * @create: 2019-09-21 10:36
 **/
public class CompletableFutureTest {

    /**
     * 核心线程 8 最大线程 20 保活时间30s 存储队列 10 有守护线程 拒绝策略:将超负荷任务回退到调用者
     * ThreadPoolExecutor.CallerRunsPolicy()在任务拒绝后，会调用当前线程池的所在的线程去执行被拒绝的任务
     * 可能会阻塞主线程
     */
    private static ExecutorService executor = new ThreadPoolExecutor(15, 20,
            30L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(1),
            new ThreadFactoryBuilder().setNameFormat("User_Async_FutureTask-%d").setDaemon(true).build(),
            new ThreadPoolExecutor.CallerRunsPolicy());


    public static void main(String[] args) {
        try {
//            runAsync();
//            supplyAsync();
            new CompletableFutureTest().supplyAsyncAndExe();
//            new CompletableFutureTest().supplyExecutor();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 无返回值  runAsync
     * @throws Exception
     */
    private static void runAsync() throws Exception{
        long startTime = System.currentTimeMillis();
        CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("run end ....");
        });
        voidCompletableFuture.get();
        System.out.println("耗时："+(System.currentTimeMillis()-startTime));
    }

    /**
     * 有返回值 没有指定Executor
     * @throws Exception
     */
    private static void supplyAsync() throws Exception{
        long startTime = System.currentTimeMillis();
        CompletableFuture<String> uCompletableFuture = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("run end ....");
            return "阿龙";
        });
        String str = uCompletableFuture.get();
        System.out.println(str);
        System.out.println("耗时："+(System.currentTimeMillis()-startTime));
    }

    private void supplyAsyncAndExe() throws Exception{
        String str="";
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(this::submit, executor);
             str = stringCompletableFuture.get();
        }
        System.out.println("耗时"+(System.currentTimeMillis()-startTime));

    }

    private String submit() {
        String str = "";
            try {
                System.out.println("当前处理线程" + Thread.currentThread().getName());
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        System.out.println("run end ....");
        return str = "成功";
    }

    private void supplyExecutor() {

        for (int i = 0; i < 10; i++) {
            executor.submit(() -> {
                try {
                    System.out.println("当前线程："+Thread.currentThread().getName());
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("run end ....");
            });
        }

    }
}
